home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
network
/
dis_pkt9.zip
/
DIS_PKT9.ASM
next >
Wrap
Assembly Source File
|
1991-11-02
|
68KB
|
2,295 lines
TITLE DIS_PKT
; DIS_PKT.ASM - Adapter provides Packet Driver v1.09 interface over NDIS.
; Version 1.07 18 May 1991 by Joe R. Doupnik, Utah State Univ.
; Version 1.08 9 Aug 1991 by Dan Lanciani, ddl@harvard.harvard.edu
; Version 1.09 3 Nov 1991 by Joe R. Doupnik, Utah State Univ.
; Copyright (C) 1988 - 1991 FTP Software, Inc.
;
; This unmodified source file and it's executable form may be used and
; redistributed freely. The source may be modified, and the source or
; executable versions built from the modified source may be used and
; redistributed, provided that this notice and the copyright displayed by
; the exectuable remain intact, and provided that the executable displays
; an additional message indicating that it has been modified, and by whom.
;
; FTP Software Inc. releases this software "as is", with no express or
; implied warranty, including, but not limited to, the implied warranties
; of merchantability and fitness for a particular purpose.
;
; USE AT YOUR OWN RISK.
;
;
; To build, using Microsoft MASM 5 or later, LINK 3.64 or later, and EXE2BIN:
;
; masm dis_pkt;
; link dis_pkt;
; exe2bin dis_pkt.exe dis_pkt.dos
; del dis_pkt.exe
; del dis_pkt.obj
;
;
;What DIS_PKT.DOS does: It provides an Ethernet or a Token Ring Packet Driver
;interface to programs built to operate over Packet Drivers. It talks
;to NDIS (3Com/Microsoft) instead of to a lan board directly. It shares
;the board with NDIS users. We call this a "shim", sitting between the
;normal applications program (NetWare shells, TCP/IP, etc) and the more
;hardware specific portions (NDIS in this case).
;
; Packet Driver flavored applications NDIS flavored applications
; || ||
; ------------- ||
; | DIS_PKT | ||
; ------------- ||
; || ||
; ------------------------------------------
; | main module |
; | NDIS ........................ |
; | board specific driver(s) |
; -------------------------------------------
; ||
; --------------------------------
; | Ethernet/Token Ring board(s) |
; --------------------------------
; ||
; =================================== Ethernet/Token Ring wire
;
;
;First sample PROTOCOL.INI file:
;
;[protocol manager]
; drivername = PROTMAN$
;
;[pktdrv] <-- name of this driver entry
; drivername = pktdrv$ <-- formal driver name
; bindings = wd8003xmac <-- use your board's NDIS driver here
; intvec = 0x60 <-- Packet Driver Int, 60h..7fh
; chainvec = 0x66 <-- post-EOI processing interrupt, unused
; novell = y <-- Optional, if present and y(es) then
; convert between old Novell 802.3 pkts
; on the wire and Type 8137 for the app.
; Omitting this line or using any other
; response turns off the conversion;
; default is no conversion.
;
;[attiso]
; drivername = ATTISO$ <-- Another NDIS client
; bindings = wd8003xmac <-- bound to the same harware driver
; nsess = 5
; ncmds = 14
; use_emm = n
;
;Western Digital EtherCard PLUS Family Adapter <-- Ethernet board
;[wd8003xmac] <-- its ndis driver
; drivername = MACWD$
; irq = 7
; ramaddress = 0xCA00
; iobase = 0x280
; receivebufsize = 1536 <-- make this a full Ethernet pkt
;
;
;
;
;Sample section of CONFIG.SYS (StarGROUP material is not required):
;
;device=c:\lanman\protman.sys /i:c:\lanman <-- must be first
;device=c:\lanman\macwd.dos <-- WD8003E driver
;device=c:\lanman\dis_pkt.dos <-- Pkt Driver (this program)
;device=c:\lanman.dos\drivers\attload.dos /Y <-- StarGROUP NDIS
;device=c:\lanman.dos\drivers\attiso\attiso.dos <-- StarGROUP NDIS
;device=c:\qemm\loadhi.sys /r:1 e:\pctcp\ifcust.sys <-- PC/TCP stuff
;device=c:\qemm\loadhi.sys /r:4 e:\pctcp\ipcust.sys <-- etc
;
;
; A second, more elaborate example, with names easier to type. We start with
;file PROTOCOL.INI. Note that semicolons start comment lines.
;
;; This is a sample protocol.ini file listing three Ethernet boards:
;; attcsma.dos is an AT&T StarLAN 10 EN100
;; elnkii.dos is a 3Com 3C503
;; wd8003.dos is a Western Digital WD8003E
;; Only one board will be selected but the other two are present.
;
;[protocol manager]
; drivername = PROTMAN$
;
;; Packet Driver protocol users tie in here
;[pktdrv]
; drivername = pktdrv$
; bindings = attcsma
;; bindings= elnkii
;; bindings = wd8003
; intvec = 0x60
;; chainvec = 0x66
; novell = no ; do not convert packet types this time
;
;; AT&T StarGROUP protocol stack ties in here via name ATTISO$
;[attiso]
; drivername = ATTISO$
; bindings = attcsma
;; bindings = elnkii
;; bindings = wd8003
; nsess = 5
; ncmds = 14
; use_emm = n
;
;;Western Digital EtherCard PLUS Family Adapter, WD8003E in this case
;[wd8003]
; drivername = MACWD$
; irq = 7
; ramaddress = 0xCA00
; iobase = 0x280
; receivebufsize = 1536
;; maxtransmits = 6
;; receivebuffers = 6
;; receivechains = 6
;
;; 3Com Etherlink II, 3C503
;[elnkii]
; drivername = ELNKII$
; ioaddress = 0x350
; interrupt = 5
; transceiver = onboard
; maxtransmits = 12
; xmitbufs = 1
;
;; AT&T StarLAN 10 EN100
;[attcsma]
; drivername = ATTCSMA$
; board_type = 2
; irq = 2
; ioaddr = 0x360
; daram = 0xD000
;
;; End of file protocol.ini
;
;Fragment of config.sys for the second example. Note three .dos board drivers.
;
;device=c:\system\ramdrive.sys 1024 512 128 /E
;device=c:\lanman\protman.sys /i:c:\lanman.dos\drivers\star10en
;device=c:\lanman\attcsma.dos
;device=c:\lanman\elnkii.sys
;device=c:\lanman\macwd.dos
;device=c:\lanman\dis_pkt.dos
;device=c:\lanman.dos\drivers\attload.dos /Y
;device=c:\lanman.dos\drivers\attiso\attiso.dos
;device=c:\qemm\loadhi.sys /r:1 e:\pctcp\ifcust.sys
;device=c:\qemm\loadhi.sys /r:4 e:\pctcp\ipcust.sys
;device=c:\qemm\loadhi.sys /r:4 c:\netdev.sys
;shell=c:\command.com /p /e:800
;
;It seems to be necessary to run NETBIND.EXE to get all this to be active.
;
;
; Edit History
; 06-Jul-89 WJR Changed interface flags in LDT to 2 per Norsk Data
; (may make vector binding work). Changed receive to
; allocate buffer for frame size instead of lookahead
; value. (This will fail miserably if the frame size
; is unknown at upcall time; such is life.) Changed
; SetPacketFilter to use module ID instead of dummy.
; 11-Sep-89 jbvb Clean up, add 1.09 functionality.
; 12-Sep-89 jbvb Don't do interrupt if vector contents are 0.
; 14-Sep-89 wjr Changed frame_rejected to frame_not_recognized to make
; vectored operation work. Changed send_pkt to use
; drv_cct.mod_id. Tried using 0 as protocol id in open
; adapter call. Changed device name to pktdrv$,
; flushed open adapter not supported message.
; 15-Sep-89 wjr Changed open adapter back to CS since 0 broke it.
; 24-Oct-89 wjr Changed FRAME_NOT_RECOGNIZED from 4 to 3
; 07-Feb-90 wjr Added push and pop SI to rcv_chn & rcv_lah.
; 02-Apr-90 wjr Fixed xmt_chn to properly check for request queued
; 03-Apr-90 wjr Given changed TCP, treat REQUEST_QUEUED as success.
; 06-Apr-90 jbvb Update patch level to 2.
; 23-Apr-90 jbvb Don't trash BP, free init code, fix comments.
; 25-Apr-90 jbvb Support "extended" calls: get/set_rcv_mode,
; get_statistics will suffice for LW.
; 26-Apr-90 jbvb Support "match all" on typelen == 0.
; 05-Jun-90 jbvb Fix stack bug in "match all" handling in access_type,
; pass valid CX on 2nd receiver() upcall, version 5.
; 13-Jun-90 jbvb Write basic set_address() code, but comment it out
; because NDIS may require a CloseAdapter first in
; order for it to work. Not worth it to me.
; 27-Jul-90 jbvb Copyright, build instructions, release v1.05.
; 24-Mar-91 jrd Rewrite great chunks to straighen out stack and DS
; addressing. This now works with Novell IPX/NETn
; and Netwatch (together as a matter of fact) and
; with PC/TCP from FTP Inc. Version to 1.06.
; Joe R. Doupnik, jrd@cc.usu.edu, Utah State Univ.
; 30-Mar-91 jrd Allow 10 byte TYPE idents to pick out packets,
; more cleanups, more needed. Promiscuous mode put last.
; Allow 20 handles. Works fine with (NetWare+PC/TCP+
; Netwatch) Pkt Drvr + Lan Man going simulanteously.
; Works with Clarkson issued Packet Driver utilities.
; 18-May-91 jrd Add filtering of packet addresses if running in
; promiscuous mode, add get current Ethernet address
; function to aid filtering, add receive mode indicator
; for each handle, correct error in snd_def initing.
; Correct problem with receive lookahead addressing.
; Compensate for 3Com drivers not preserving regs.
; Bump up NDIS tables to v2. Dis_pkt version to 1.07.
; 09-Aug-91 ddl 802.5, 802.3 support; default binding; overwrite fix
; 03-Nov-91 jrd Add keyword NOVELL to PROTOCOL.INI to convert between
; old Novell 802.3 packets on the wire to 8137 for the
; applications program. Convert if the line is present
; and the value is y(es). Small cleanups.
PAGE ,80
EOL EQU <13, 10, '$'>
LF = 10
CR = 13
EOS = '$'
DOS equ 21h
prstr equ 9
fopen equ 3dh
fclose equ 3eh
ioctl equ 44h
MSG MACRO TEXT
PUSH DX ;; save DX across call
push ax
push ds
mov ax,cs
mov ds,ax
MOV DX,OFFSET TEXT ;; point to message
mov ah,prstr ; display dollar terinated string
int dos
pop ds
pop ax
POP DX
ENDM
; DOS request header offsets
command = 2
status = 3
bpb = 18
end_off = 14
end_seg = 16
; NDIS General Request codes
INIT_DIAG equ 1
READ_ERR_LOG equ 2
SET_STA_ADDR equ 3
OPEN_ADAPTER equ 4
CLOSE_ADAPTER equ 5
RESET_MAC equ 6
SET_PKT_FLT equ 7
ADD_MULT_ADDR equ 8
DEL_MULT_ADDR equ 9
UPDATE_STATS equ 10
CLEAR_STATS equ 11
INTERRUPT_ME equ 12
SET_FUNC_ADDR equ 13
SET_LOOKAHEAD equ 14
ADDR_NONE EQU 0 ; NDIS Receiver modes: disabled
ADDR_MULT EQU 1 ; Receive packets for my address & multicast
ADDR_BRD EQU 2 ; Receive broadcast packets
ADDR_PROM EQU 4 ; Receive all packets (promiscuous mode)
ADDR_SRCRT EQU 8 ; Receive all source-routed packets
; Protocol to MAC return codes
SUCCESS EQU 0
REQUEST_QUEUED EQU 2
FRAME_NOT_RECOGNIZED EQU 3
NOT_SUPPORTED EQU 9
GENERAL_FAILURE EQU 0FFH
; NDIS-related structure definitions
cct_def struc
dw 64 ; Size of common characteristics table (cct)
dw 0 ; Level of cct (zero this version)
dw 0 ; Level of service-specific subtables
db 2 ; Major module version (2 BCD digits)
db 0 ; Minor module version (2 BCD digits)
dd 2 ; Module function flags
db 'PKTDRV$', 9 dup (0) ; Module name, 16 byte ASCIIZ format
db 4 ; Protocol level at upper boundary of module
db 0 ; type of interface at upper module boundary
db 1 ; protocol level at lower boundary of module
db 1 ; type of interface at lower module boundary
mod_id dw -1 ; module ID filled in by Protocol Manager
mod_ds dw 0 ; module DS
system dd 0 ; system request dispatch entry point
sscp dd 0 ; pointer to service-specific characteristics
sssp dd 0 ; pointer to service-specific status
udtp dd 0 ; pointer to upper dispatch table
ldtp dd 0 ; pointer to lower dispatch table
dd 0 ; reserved (must be NULL)
dd 0 ; reserved (must be NULL)
cct_def ends
ssc_def struc
dw 94 ; length of MAC service-specific
; characteristics table (ssc)
mtype db 16 dup (0) ; type name of MAC, ASCIIZ format
dw 0 ; length of station addresses in bytes
db 16 dup (0) ; permanent station address
cur_add db 16 dup (0) ; current station address
dd 0 ; current functional address of adapter
dd 0 ; multicast address list
dd 0 ; link speed
svc_1 dw 0 ; service flags
svc_2 dw 0 ; service flags
maxfram dw 0 ; max frame size both sent and recv
dd 0 ; total transmission buffer cap in driver
dw 0 ; transmission buffer allocation block size
dd 0 ; total reception buffer cap in driver
dw 0 ; reception buffer allocation block size
db 3 dup (0) ; IEEE vendor code (OUI)
db 0 ; vendor adapter code
dd 0 ; vendor adapter description pointer
dw 0 ; IRQ of adapter (NDIS v2)
dw 0 ; transmit queue depth (NDIS v2)
ssc_def ends
sss_def struc
dw 0 ; length of status table
dd 0 ; date/time of last diagnostics
dd 0 ; MAC status
dw 0 ; current packet filter
dd 0 ; pointer to media specific statistics table
dd 0 ; date/time of last ClearStatistics call
r_tot dd 0 ; total frames received
r_crc dd 0 ; frames with CRC error
rb_tot dd 0 ; total bytes received
r_drop dd 0 ; frames discarded - no buffer space
r_mult dd 0 ; multicast frames received
r_bro dd 0 ; broadcast frames received
r_err dd 0 ; frames received with errors
r_big dd 0 ; frames exceeding maximum size
r_runt dd 0 ; frames smaller than minimum size
rb_mul dd 0 ; multicast bytes received
rb_bro dd 0 ; broadcast bytes received
r_hwer dd 0 ; frames discarded - hardware error
x_tot dd 0 ; total frames transmitted
xb_tot dd 0 ; total bytes transmitted
x_mul dd 0 ; multicast frames transmitted
x_bro dd 0 ; broadcast frames transmitted
xb_bro dd 0 ; broadcast bytes transmitted
xb_mul dd 0 ; multicast bytes transmitted
x_tmo dd 0 ; frames not transmitted - time-out
x_hwer dd 0 ; frames not transmitted - hardware error
sss_def ends
udt_def struc ; upper dispatch table
dd 0 ; back pointer to cct
reqadd dd 0 ; request address
xchain dd 0 ; TransmitChain address
dd 0 ; TransferData address
dd 0 ; ReceiveRelease address
indon dd 0 ; IndicationOn address
indoff dd 0 ; IndicationOff address
udt_def ends
ldt_def struc ; lower dispatch table
dd 0 ; back pointer to cct
dd 2 ; interface flags (2 means something)
dd 0 ; RequestConfirm address
dd 0 ; TransmitConfirm address
dd 0 ; ReceiveLookahead indication address
dd 0 ; IndicationComplete address
dd 0 ; ReceiveChain indication address
dd 0 ; status indication address
ldt_def ends
snd_def struc ; transmit buffer descriptor
dw 0 ; byte count of immediate data (always 0)
dd 0 ; address of immediate data
dw 1 ; count of data blocks (always 1)
db 0 ; pointer type (0 == physical)
db 0 ; reserved
snd_len dw 0 ; number of bytes to send
snd_off dw 0 ; offset of data to send
snd_seg dw 0 ; segment of data to send
snd_def ends
rcv_def struc ; receive buffer descriptor
dw 1 ; count of data blocks (always 1)
db 0 ; pointer type (0 == physical)
db 0 ; reserved
rcv_len dw 0 ; number of bytes to get
rcv_off dw 0 ; offset of data to get
rcv_seg dw 0 ; segment of data to get
rcv_def ends
req_def struc ; Request block - Protocol Manager primitives
req_opc dw 0 ; opcode for PM request
req_sta dw 0 ; status returned from request
req_of1 dw 0 ; first parameter pointer
req_sg1 dw 0
req_of2 dw 0 ; second parameter pointer
req_sg2 dw 0
req_prm dw 0 ; parameter word
req_def ends
bnd_def struc ; binding list
bnd_cnt dw 1 ; number of MACs to bind to -- 0 or 1
bnd_nam db 16 dup (0) ; name of module to bind to
bnd_def ends
SUBTTL Resident Data Area
PAGE
CSEG SEGMENT PARA PUBLIC 'CODE'
assume cs:CSEG, ds:CSEG, es:nothing
; DEVICE HEADER - must be at offset zero within device driver
DD -1 ; becomes pointer to next device header
DW 8000H ; attribute (char device)
DW OFFSET strat ; pointer to device strategy routine
DW OFFSET intr ; pointer to device interrupt handler
DB "PKTDRV$ " ; device driver name
; END OF DEVICE HEADER
mac_cctp dd 0 ; address of MAC's cct table
mac_ds dw 0 ; DS register for MAC
rtn_cod dw 0 ; Save NDIS return code here
drv_cct cct_def <> ; Common Characteristics Table
drv_ldt ldt_def <> ; Lower Dispatch Table
drv_snd snd_def <> ; Argument blocks for NDIS TransmitChain,
drv_rcv rcv_def <> ; TransferData,
drv_bnd bnd_def <> ; and Bind (via DOS IOCTL)
drv_req req_def <> ; Argument block for general NDIS requests
TransmitChain dd 0 ; MAC entry point to send packet
TransferData dd 0 ; MAC entry point for data copy
Request dd 0 ; MAC entry point for requests
ReceiveRelease dd 0 ; MAC entry point (???not used???)
IndicationOn dd 0 ; MAC entries to control Indications
IndicationOff dd 0 ; (upcalls) from NDIS
req_con_flg dw REQUEST_QUEUED ; Completion status from NDIS upcall
init_flg db 0 ; Non-zero if we've been initialized
address db 16 dup (0) ; Current address from MAC
bytcnt dw 0 ; Bytes copied by TransferData
xmt_cmp dw SUCCESS ; TransmitChain result
open_adap dw 0 ; OpenAdapter & SetPacketFilter result
; Request Header (RH) address, saved here by "strategy" routine
req_hdr LABEL DWORD
req_off dw 0
req_seg dw 0
; Save the request header for use by the interrupt routine
strat PROC FAR
mov word ptr cs:req_off,bx ; offset
mov word ptr cs:req_seg,es ; segment
ret
strat ENDP
EVEN ; Get into word alignment
;;
;; Data for Packet Driver
;;
BAD_HANDLE EQU 1 ; invalid handle number
NO_CLASS EQU 2 ; no interfaces of this class found
NO_TYPE EQU 3 ; no interfaces of specified type found
NO_NUMBER EQU 4 ; no interfaces of specified number found
BAD_TYPE EQU 5 ; bad packet type specified
NO_MULTICAST EQU 6 ; this interface does not support multicast
CANT_TERMINATE EQU 7 ; this packet driver cannot terminate
BAD_MODE EQU 8 ; an invalid receiver mode was specified
NO_SPACE EQU 9 ; operation failed because of insufficient space
TYPE_INUSE EQU 10 ; type had previously been accessed and not released
BAD_COMMAND EQU 11 ; the command was out of range or not implemented
CANT_SEND EQU 12 ; the packet couldn't be sent (usually hardware error)
CANT_SET EQU 13 ; The hardware address couldn't be changed
BAD_ADDRESS EQU 14 ; Hardware address has bad length or format
CANT_RESET EQU 15 ; Couldn't reset interface (more than 1 handle open)
PD_LEVEL EQU 6 ; Implementation level (basic, high perf, ext)
ANY_TYPE EQU 0FFFFh ; Matches any if_type
ETHERADDR_LEN EQU 6 ; Length of an Ethernet address
ETHERTYPE_LEN EQU 2 ; Length of Ethertypes
ETHERTYPE_NONE EQU 0 ; Ethertypes of 0 mean not defined
; The connection arrays: types, and corresponding upcalls
PD_MAX_CONNS EQU 20 ; The maximum number of handles/Types that can
; be registered at one time
MAX_P_LEN equ 10 ; max length of TYPE matching field, bytes
per_handle struc ; Packet Driver HANDLE structure
pd_conn_used db 0 ; non-zero if this handle is in use
pd_conn_type db MAX_P_LEN dup(0) ; associated packet type
pd_conn_type_len dw 0 ; associated packet type length
pd_conn_rmode dw 3 ; receive mode for this handle
pd_conn_rcvr dd 0 ; receiver handler address
pd_conn_class db 0 ; interface class
per_handle ends
handles per_handle PD_MAX_CONNS dup(<>)
end_handles label byte
novell db 0 ; if non-zero convert between old
; Novell 802.3 interior to Type 8137
; Caller used 8137, wire gets 802.3
; Because some NDIS drivers can't support multiple calls to TransferData
; for a single reception, we only allow one handle (by implication, the last),
; to be in "match all" mode at a given time, but we do allow other handles
; to be open at the same time.
if_class DB 1 ; Class 1 is Ethernet
if_type DW 57 ; NDIS to Packet Driver adapter
pd_version DW 9 ; Version
conn_in_use DW 0 ; Number of handles open
pd_vector DW -1 ; Packet Driver vector to serve on
pd_rcv_mode DW 3 ; Default to rcv mode 3 (normal/bcast)
pd_name DB "MAC/DIS converter", 0
pd_recvall db 0 ; non-zero if Promiscuous mode is active
off dw 12 ; offset to match bytes
aoff dw 0 ; offset to addresses
; Table re-maps (badly) NDIS modes to Packet Driver modes (in parentheses)
ndis_mode db 0 ; No packets (0 == illegal)
db 0 ; No packets (1 == receiver off)
db 1 ; Directed | Multicast (2 should be directed only)
db 3 ; Directed | Multicast | Broadcast
; (3 should be directed | broadcast)
db 3 ; Directed | limited Multicast | Broadcast
; (4 == directed | broadcast | limited multicast)
db 3 ; Directed | limited Multicast | Broadcast
; (5 should be directed | broadcast | all multicast)
db 4 ; Promiscuous (6 == match all)
EVEN ; Get into word alignment
; struct param; Pointer to this returned by get_parameters()
pd_param db 1 ; Major revision = 1
db 9 ; Minor revision = 9
db 14 ; Length of this structure = 14
db ETHERADDR_LEN ; MAC addr length
mtu dw 1514 ; MAC packet length
dw 0 ; No multicast support
dw 0 ; No promises re: back-to-back receives
dw 0 ; No promises re: back-to-back transmits
param_int dw 0 ; Default to no interrupt on EOI
; Pointer to this returned by get_statistics
pd_statistics struc
pkt_in dd 0 ; Total packets in
pkt_out dd 0 ; Total packets out
bytes_in dd 0 ; Total bytes received
bytes_out dd 0 ; Total bytes sent
errs_in dd 0 ; Total transmit errors
errs_out dd 0 ; Total receive errors
pkts_lost dd 0 ; Packets dropped - no buffer, out of resc
pd_statistics ends
pd_stat pd_statistics <> ; An instance of the above
PUBLIC driver_info, access_type, release_type, send_pkt, terminate
PUBLIC get_address, reset_interface, get_parameters, set_rcv_mode
PUBLIC get_rcv_mode, get_statistics, set_address
; Normal (basic Packet Driver functions) Jump Table
pd_table DW pd_none ; No handler
DW driver_info ; 1
DW access_type ; 2
DW release_type ; 3
DW send_pkt ; 4
DW terminate ; 5
DW get_address ; 6
DW reset_interface ; 7
pd_table_size EQU ($-pd_table)/2
; High Performance functions Jump Table
hp_table DW get_parameters ; 10
DW pd_none ; 11 (as_send_pkt not implemented)
hp_table_size EQU ($-hp_table)/2
; Extended functions Jump Table
ext_table DW set_rcv_mode ; 20
DW get_rcv_mode ; 21
DW pd_none ; 22 (set_multicast_list not implemented)
DW pd_none ; 23 (get_multicast_list not implemented)
DW get_statistics ; 24
DW set_address ; 25
ext_table_size EQU ($-ext_table)/2
;
; rcv_lah is the proc that handles ReceiveLookAhead upcalls from the MAC
;
; First, it determines if the packet is one that is wanted. If so, it asks
; the appropriate application for a buffer. If it gets one, it copies the
; data and makes the 2nd call to the application to post it complete. If
; not, it returns SUCCESS to the DIS driver anyway. It returns SUCCESS if
; if the packet was copied or FRAME_NOT_RECOGNIZED if it is not in the list
; of desired types.
;
;The stack coming into this call is:
; dw bp[20] MACID
; dw bp[18] framesize
; dw bp[16] bytes available in buffer
; dw bp[14] lookahead data address seg
; dw bp[12] lookahead data address off
; dd bp[10] indicate flag
; dw bp[6] ds of called protocol mode (ME)
;
rcv_lah PROC FAR
push bp
mov bp,sp
push bx ; -2[bp] ; save things
push cx ; -4[bp]
push dx ; -6[bp]
push di ; -8[bp]
push ds ; -10[bp]
push es ; -12[bp]
sub sp,6 ; -14[bp] handle
; -16[bp] seg of PD buffer
; -18[bp] offset of PD buffer
push si
mov ax,cs ; setup data segment
mov ds,ax
mov ax,14[bp] ; segment of lookahead buffer
mov es,ax
mov di,12[bp] ; and its offset
call pktfilter ; apply packet filter
jnc lah_get_buf ; nc = we want this packet
mov ax,FRAME_NOT_RECOGNIZED ; packet not accepted
jmp lah_don
lah_get_buf: ; Call Packet Driver receive routine to get its buffer address
mov cx,18[bp] ; CX = packet length
xor ax,ax ; AX = 0, 1st call to receiver
mov -14[bp],bx ; BX = handle, for next call
push bp ; we depend on BP
call dword ptr cs:[bx].pd_conn_rcvr ; Call the receive routine
pop bp ; Get BP back
mov ax,es ; Buffer address is in ES:DI
or ax,ax ; Check for segment of buffer,
jnz rcvlha4 ; nz = ok
or di,di ; Check for offset of buffer,
jnz rcvlha4 ; nz = ok
mov ax,SUCCESS ; No copy, accept pkt anyway
jmp lah_don
rcvlha4: ; Get data into buffer
mov -16[bp],es
mov -18[bp],di ; save PD buffer pointer
mov ax,offset bytcnt ; Create far pointer to Addr
push ds ; to put bytes copied into
push ax ; and push it
xor ax,ax ; Starting offset in frame
push ax ; is always zero
;
; Set up recv table description
;
mov ax,18[bp] ; Len of recv data
mov drv_rcv.rcv_len,ax ; goes in argument descriptor
mov drv_rcv.rcv_seg,es ; as does far address of
mov drv_rcv.rcv_off,di ; receive buffer
push ds ; Push far pointer to
mov ax,offset drv_rcv ; descriptor
push ax
mov ax,mac_ds ; Push MAC's DS value
push ax
call dword ptr cs:TransferData ; Copy pkt to buf (pops args)
;
; Call Packet Driver receive routine again (AX = 1) to finish up
;
mov ax,-16[bp] ; recover PD buffer pointer
mov ds,ax
mov si,-18[bp] ; to DS:SI for second PD call
mov cx,18[bp] ; CX = packet length
mov bx,-14[bp] ; BX = handle
mov ax,1 ; AX = 1 (second call)
call dword ptr cs:[bx].pd_conn_rcvr ; Call receive routine again
mov ax,SUCCESS ; we accepted the packet
lah_don:pop si
add sp,6 ; local material
pop es
pop ds
pop di
pop dx
pop cx
pop bx
pop bp
ret 16 ; Pop MAC's params off stack
rcv_lah ENDP
;
; rcv_chn is the proc that handles ReceiveChain upcalls from the MAC
;
; First, it determines if the packet is one that is wanted. Then it tranfers
; the data into an internal buffer. it blocks any new indications until the
; indicate complete upcall allows it the time to do a packet driver upcall.
; It returns success if the packet is ok or FRAME_NOT_RECOGNIZED if it is not
; in the list of currently open types.
;
; The stack coming into this call is:
; dw bp[20] MACID
; dw bp[18] framesize
; dw bp[16] request handle
; dw bp[14] receive-chain buf descriptor address seg
; dw bp[12] receive-chain buf descriptor address off
; dd bp[8] indicate flag addr
; dw bp[6] DS of called protocol mode (ME)
;
; where receive-chain buffer descriptor format is
; dw rxdatacount count of received data blocks, max of 8
; dw rxdatalen length of a data block
; dd rxdataptr seg:offset of a data block
rcv_chn PROC FAR
push bp
mov bp,sp
push bx ; -2[bp] ; save things
push cx ; -4[bp]
push dx ; -6[bp]
push di ; -8[bp]
push ds ; -10[bp]
push es ; -12[bp]
sub sp,2 ; -14[bp] handle
push si
mov ax,cs ; setup data segment (== CS)
mov ds,ax
mov ax,14[bp] ; seg of rcv-chain buffer descriptor
mov es,ax
mov di,12[bp] ; and its offset
les di,es:[di+4] ; es:di is now the buffer pointer
call pktfilter ; apply packet filter, return handle
jnc chn_get_buf ; nc = we want this packet
mov ax,FRAME_NOT_RECOGNIZED ; packet not accepted
jmp chn_don
;; Call the Packet Driver receive routine to get its buffer address
chn_get_buf:
mov cx,18[bp] ; CX = packet length
xor ax,ax ; AX = 1st call to receiver
mov -14[bp],bx ; remember handle for next call
push bp ; We depend on BP
call dword ptr cs:[bx].pd_conn_rcvr ; Call the receive routine
pop bp ; Restore BP
; Now protocol stack's buffer address is in ES:DI
mov ax,es
or ax,ax ; Check for non-zero segment
jne rcvchn4 ; ne = ok
or di,di ; Check for non-zero offset
jne rcvchn4 ; ne = ok
mov ax,SUCCESS ; No copy, accept pkt anyway
jmp chn_don
rcvchn4: ;; Get data from NDIS buffer(s) into protocol stack's buffer
push ds ; Save to restore after call
push es ; Save ES:DI (pointer) to pass
push di ; back to receiver later
lds si,12[bp] ; Addr of rcv descriptor
mov cx,[si] ; Get number of data blocks
add si,2 ; & move to top of list
chn_dat: ; Move data from next block into stack's buffer
push cx
push ds
push si
mov cx,[si] ; Get byte count of block
add si,2
lds si,[si] ; Get far pointer to data
cld
shr cx, 1
jnc rcvchn5 ; nc = even already
movsb ; Move 1 byte if count is odd
rcvchn5:rep movsw ; Use word mov for efficiency
pop si ; Go through rest of chain
add si,6
pop ds
pop cx
loop chn_dat ; For all blocks
;
; Call Packet Driver receive routine again to finish up
;
pop si ; DS:SI = buffer pointer
pop ds ; that we're completing
mov cx,18[bp] ; CX = packet length
mov bx,-14[bp] ; BX = handle
mov ax,1 ; Indicate 2nd (AX == 1) call
call dword ptr cs:[bx].pd_conn_rcvr ; Call receive routine again
mov ax,SUCCESS ; We accepted the packet
pop ds ; Now we're done with DS
chn_don:pop si
add sp,2
pop es
pop ds
pop di
pop dx
pop cx
pop bx
pop bp
ret 16 ; pop params off stack
rcv_chn ENDP
; Worker for lookahead and receive_chain procedures above. Checks PD handles
; for wanting this kind of packet. Returns carry clear and BX = handle
; if packet is wanted, else carry set to reject the packet. Expects MAC layer
; to provide at least our needed number of bytes (14+).
; Destroys AX, CX, DX, SI, preserves DI, ES, sets BX. Expects DS = CS.
pktfilter proc near
cmp conn_in_use,0 ; any requests active?
jnz pktfil1 ; e = no, exit no-match
jmp pktfil11
pktfil1:mov dx,di ; es:di is data pointer, save here
mov bx,offset handles ; BX = offset of handle table
mov cx,PD_MAX_CONNS ; CX = entries in table
pktfil2:push cx ; save loop counter
cmp [bx].pd_conn_used,0 ; is handle in use?
jne pktfil4
jmp pktfil9 ; e = no, do next handle
pktfil4:lea si,[bx].pd_conn_type ; TYPE wanted by this handle
mov cx,[bx].pd_conn_type_len; number of bytes to match
or cx,cx
jnz pktfil6 ; nz = do not match all packets
pktfil5:jmp pktfil12 ; match all packets
pktfil6:mov ax,[bx].pd_conn_rmode ; receive mode
cmp ax,6 ; Promiscuous?
je pktfil5 ; e = yes, accept packet
mov di,dx ; es:di is lookahead data ptr
cmp if_class,3 ; Token Ring 802.5 Class 3 interface?
jne pktfil7 ; ne = no
test byte ptr es:8[di],80h ; routing info present?
jz pktfil7 ; z = no
push cx
mov cl,es:14[di] ; get length of routing info
and cx,1fh ; just 5 bits worth
add di,cx ; skip over routing info
pop cx
pktfil7:add di,off ; skip to TYPE field et seq
; do old Novell 802.3 to Type 8137
cmp if_class,1 ; regular Ethernet?
jne pktfil8 ; ne = no
cmp novell,0 ; doing old Novell conversion?
je pktfil8 ; e = no
cmp word ptr es:[di+2],0ffffh ; have the bad DSAP/SSAP signature?
jne pktfil8 ; ne = no
mov ax,es:[di] ; get length/Type field value
xchg ah,al ; low endian form
cmp ax,1500 ; size is larger than length?
jae pktfil8 ; ae = yes, a protocol type
mov word ptr es:[di],3781h ; force in Novell Type 8137
; end of Novell section
pktfil8:cld
repe cmpsb ; check for matching TYPE
je pktfil12 ; e = match
; If Promiscuous mode do manual filter
cmp pd_recvall,0 ; doing Promiscuous mode?
je pktfil9 ; e = no, next handle
mov si,offset address ; our board's Ethernet addr
mov cx,ETHERADDR_LEN ; length of an Ethernet address
mov di,dx ; lookahead buffer
add di,aoff
cld ; look at destination address
repe cmpsb ; look for our Ethernet address
je pktfil12 ; e = matched, accept lookahead
cmp ax,2 ; ignore multicast and broadcast?
jbe pktfil9 ; be = yes
mov di,dx ; recover offset of start of buffer
add di,aoff
test byte ptr es:[di],80h ; multicast bit set?
jnz pktfil12 ; nz = yes, accept lookahead
cmp ax,3 ; accepting broadcasts?
jb pktfil9 ; b = no
mov al,0ffh ; look for broadcast
mov cx,ETHERADDR_LEN
repe scasb ; scan for all 0xFF's
je pktfil12 ; e = matched, a broadcast
pktfil9:add bx,size per_handle ; next entry
pop cx ; recover loop counter
dec cx ; mechanical loop
or cx,cx ; end of loop?
jz pktfil10 ; z = yes
jmp pktfil2 ; try next one
pktfil10:mov di,dx ; restore di
pktfil11:stc ; carry set = no match found
ret
pktfil12:pop cx ; clean loop counter from stack
mov di,dx ; restore di
clc ; carry clear = have match
ret
pktfilter endp
;
; Services indication complete upcall
;
; Executes interrupt (returned by get_parameters()) to pass control to
; an application which wants to run after the EOI.
;
; NOTE: Interrupt number at label ind_int is over-written if a different
; interrupt is configured in protocols.ini.
;
ind_com PROC FAR ; Indication_complete upcall
push es
push bx
xor ax,ax
mov es,ax ; Point ES at interrupt segment
mov bx,cs:param_int ; Get offset of vector
or bx,bx ; Is there one?
jz ind_no_int ; z = no, don't do the interrupt
shl bx,1 ; Multiply by 4 for memory offset
shl bx,1
cmp word ptr es:[bx]+2,0 ; Is there a segment there?
jne ind_int ; ne = yes
cmp word ptr es:[bx],0 ; Is there an offset there?
je ind_no_int ; no, no interrupt
ind_int: ; INT 65 overwritten if selected
INT 65h ; Pass control to the application
ind_no_int:
pop bx ; Restore registers
pop es
mov ax,SUCCESS
ret 4
ind_com ENDP
;;;;;;;;;;;;;;;;;;;;;;;;; Packet Driver section
regs struc ; stack offsets of incoming regs
_ES dw ?
_DS dw ?
_BP dw ?
_DI dw ?
_SI dw ?
_DX dw ?
_CX dw ?
_BX dw ?
_AX dw ?
_IP dw ?
_CS dw ?
_F dw ? ; flags, Carry flag is bit 0
regs ends
bytes struc ; stack offsets of incoming regs
dw ? ; es, ds, bp, di, si are 16 bits
dw ?
dw ?
dw ?
dw ?
_DL db ?
_DH db ?
_CL db ?
_CH db ?
_BL db ?
_BH db ?
_AL db ?
_AH db ?
bytes ends
CY equ 0001h ; to set caller's carry bit
;
; Interrupt handler for the Packet Driver interface (protocol stack downcalls)
;
; NOTE: Leaves interrupts disabled on entry - code in access_type and
; release_type depends on this. send_pkt enables interrupts for MAC.
;
PUBLIC pd_isr
pd_isr PROC FAR
jmp short over ; skip the string (this MUST be a 3 byte jmp)
nop ; make three bytes
DB "PKT DRVR",0 ; string to identify a packet driver
over:
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
cld
push cs ;set up ds to this code segment
pop ds
mov bp,sp ;we use bp to access the original regs
and _F[bp],not CY ;start by clearing the carry flag
mov _DH[bp],0 ; put no-error code in caller's DH
cmp ah,pd_table_size ; AH too large?
jae highperf_table ; ae = yes, try next set
; Dispatch on AH using normal table
mov bl,ah ; Get function code
xor bh,bh ; into a word register
shl bx,1 ; index by words
jmp pd_table[bx] ; and go
highperf_table:
sub ah, 10 ; Offset of 1st high-performance function
jl pd_none ; l = ah is out of range
cmp ah,hp_table_size ; is AH still in range?
jae xtend_table ; ae = no, try next set
; Dispatch on AH using high-performance table
mov bl,ah ; Get function code
xor bh,bh ; into a word register
shl bx,1 ; index by words
jmp hp_table[bx] ; and go
xtend_table:
sub ah,10 ; Offset of 1st extended function
jl pd_none ; l = AH is not in range
cmp ah,ext_table_size ; still in range?
jae pd_none ; ae = no
; Dispatch on AH using extended table
mov bl,ah ; Get function code
xor bh,bh ; into a word register
shl bx,1 ; index by words
jmp ext_table[bx] ; and go
pd_none:
mov dh,BAD_COMMAND ; set error code
err_ret:
mov _DH[bp],dh ; put error code in caller's DH
or _F[bp],CY ; set caller's carry flag
good_ret: ; good return (carry clear)
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
;
; Checks the handle in BX. If out of range or not valid cleans up the
; stack and jumps directly to err_ret with a BAD_HANDLE error. Assumes
; called with DS pushed and a near call. If handle is good, just returns.
; BX is shifted one bit to the left.
;
; Bounds check on handle
chk_hdl PROC NEAR
mov bx,_BX[BP] ; Handle
cmp bx,offset handles ; start of handles area
jb chkhdl1 ; b = out of range
cmp bx,offset end_handles ; end of handles area
jae chkhdl1 ; ae = above max table size
cmp [bx].pd_conn_used,0 ; is handle used?
je chkhdl1 ; e = no, go bomb out
ret ; return BX as handle
chkhdl1:
pop ds ;clear stack (was the return address)
mov dh,BAD_HANDLE ;return BAD_HANDLE error
jmp err_ret
chk_hdl ENDP
; The following implement the individual Packet Driver commands, basic
; functions first.
;
; Send a packet.
;
send_pkt:
mov xmt_cmp,REQUEST_QUEUED ; set up for queued data
mov bx,_BX[bp] ; handle
mov dx,_DS[bp] ; get ds of data block to dx
mov cx,_CX[bp]
mov si,_SI[bp]
mov ax,drv_cct.mod_id ; put our module id
push ax
push ds ; request handle - good as any
; do conversion of Type 8137 to old Novell 802.3
cmp if_class,1 ; regular Ethernet?
jne send_pkt3 ; ne = no, no conversion
cmp novell,0 ; doing Novell packet conversion?
je send_pkt3 ; e = no
push es
mov es,dx ; segment of packet
cmp word ptr es:[si+12],3781h ; outgoing Novell Type 8137?
jne send_pkt2 ; ne = no
mov ax,es:[si+12+4] ; get internal length indicator
xchg ah,al
inc ax ; round up to an even length
and al,not 1
xchg ah,al
mov es:[si+12],ax ; change packet Type field to length
send_pkt2:pop es ; end of Novell conversion
send_pkt3:
mov drv_snd.snd_len,cx ; save byte count in descriptor
mov drv_snd.snd_off,si ; store offset of pkt buffer
mov drv_snd.snd_seg,dx ; store segment of pkt buffer
mov bx,offset drv_snd ; get addr of xmit buff desc
push ds ; store on stack
push bx
mov ax,mac_ds ; MACID
push ax
sti ; enable ints just to be sure
call TransmitChain ; do downcall to NDIS
xor dx,dx ; clear return code
cmp ax,SUCCESS ; done?
je send_pkt4 ; e = yes, success
cmp ax,REQUEST_QUEUED ; queued?
jne send_pkt5 ; ne = no
send_pkt4:jmp good_ret ; queued is ok
send_pkt5:
mov dh,CANT_SEND ; trouble, fail
jmp err_ret
;
; Handle driver_info() downcall - return driver information.
;
driver_info:
mov bx,pd_version ; BX is version
mov ch,if_class ; CH is class
mov dx,if_type ; DX is type
xor cl,cl ; CL is interface number (always 0)
mov _BX[bp],bx
mov _CX[bp],cx
mov _DX[bp],dx
mov _SI[bp],offset pd_name ; ds:si is ptr to name
mov ax,ds
mov _DS[bp],ax
mov al,PD_LEVEL ; Level of implementation
xor ah,ah
mov _AX[bp],ax
jmp good_ret
;
; Handle access_type() - sets up to handle an Ethernet packet type.
;
; NOTE: Depends on entry with interrupts disabled for shared data locking.
;
access_type_class:
mov dh,NO_CLASS
jmp err_ret
access_type_type:
mov dh,NO_TYPE
jmp err_ret
access_type_number:
mov dh,NO_NUMBER
jmp err_ret
access_type_bad:
mov dh,BAD_TYPE
jmp err_ret
access_type:
mov al,if_class
cmp _AL[bp],al ; our class?
jne access_type_class ; ne = no, fail
access_type_1:
; cmp _BX[bp],ANY_TYPE ; generic type?
; je access_type_2 ; e = yes
; mov al,driver_type
; cbw
; cmp _BX[bp],ax ; our type?
; jne access_type_type ; ne = no
access_type_2:
cmp _DL[bp],0 ; generic number?
je access_type_3 ; e = yes
cmp _DL[bp],1 ; our number?
jne access_type_number ; ne = no
access_type_3:
cmp _CX[bp],MAX_P_LEN ; is the type length too long?
ja access_type_bad ; a = yes, this can't be ours
; now we do two things--look for an open handle, and check the existing
; handles to see if they're replicating a packet type.
xor dx,dx ; remember no free handle yet
mov bx,offset handles ; first handle
cld
access_type_4:
cmp [bx].pd_conn_used,0 ; is this handle in use?
je access_type_5 ; e = no, do not check the type
mov al,_AL[bp] ; is this handle the same class as
cmp al,[bx].pd_conn_class ; they want?
jne short access_type_6 ; ne = no
mov es,_DS[bp] ; get a pointer to their type
mov di,_SI[bp] ; from their ds:si to our es:di
mov cx,_CX[bp] ; get the minimum of their length
; and our length. As currently
; implemented, only one receiver
; gets the packets, so we have to
; ensure that the shortest prefix
; is unique.
mov si,[bx].pd_conn_type_len ; length of their Type
cmp cx,si ; are we less specific than they are?
jb access_type_8 ; b = no
mov cx,si ; yes, use their (shorter) length
access_type_8:
lea si,[bx].pd_conn_type ; their desired Type
or cx,cx ; pass-all TYPE? (zero TYPE length)
jnz access_type_7 ; nz = no
mov bx,offset handles+(PD_MAX_CONNS-1)*(size per_handle)
jmp short access_type_5 ; put pass-all last
access_type_7:
repe cmpsb ; same type? (conflict if so)
jne short access_type_6 ; ne = no, go look at the next one
access_type_inuse:
mov dh,TYPE_INUSE ; a handle has been assigned for TYPE
jmp err_ret ; cannot assign a type
access_type_5: ; handle is not in use
or dx,dx ; found a free handle yet?
jne access_type_6 ; ne = yes
mov dx,bx ; remember first free handle in dx
access_type_6:
add bx,(size per_handle) ; go to the next handle
cmp bx,offset end_handles ; examined all handles?
jb access_type_4 ; b = no, continue
mov bx,dx ; did we find a free handle?
or bx,bx
jz access_type_space ; z = no, return error
mov [bx].pd_conn_used,1 ; remember that we're using it
mov ax,_DI[bp] ; get receiver address from ES:DI
mov word ptr [bx].pd_conn_rcvr,ax ; offset part
mov ax,_ES[bp]
mov word ptr [bx].pd_conn_rcvr+2,ax ; segment part
push ds
mov ax,ds
mov es,ax
mov ds,_DS[bp] ; remember their type
mov si,_SI[bp]
mov cx,_CX[bp]
mov es:[bx].pd_conn_type_len,cx ; remember the TYPE length
lea di,[bx].pd_conn_type
rep movsb ; copy TYPE field to match
pop ds
inc conn_in_use ; count handles in use
mov al,_AL[bp] ; remember Class
mov [bx].pd_conn_class,al
mov _AX[bp],bx ; return handle in caller's AX
call chk_rmode ; update Promiscous mode status
jmp good_ret
access_type_space:
mov dh,NO_SPACE
jmp err_ret
;
; Perform release_type() - forget the packet type/upcall/handle
;
; NOTE: Depends on entry with interrupts disabled for shared data locking.
;
release_type:
call chk_hdl ; get handle, return here if ok
; This is a critical region!!
mov [bx].pd_conn_type,ETHERTYPE_NONE ; Clear connection
mov [bx].pd_conn_used,0 ; free handle-used indicator
dec conn_in_use ; Count one less handle open
call chk_rmode ; update Promiscous mode status
jmp good_ret
;
; Perform terminate() - never actually do it.
;
terminate:
call chk_hdl ; check handle
mov dh,CANT_TERMINATE ; Return error
jmp err_ret
;
; Perform get_address() - get the current Ethernet address of the interface
;
get_address:
mov ax,_AX[bp]
mov bx,_BX[bp]
mov cx,_CX[bp]
mov si,_SI[bp]
mov di,_DI[bp]
mov es,_ES[bp]
cld
cmp cx,ETHERADDR_LEN ; Make sure it's an ethernet address
jne get_address_err ; ne = bad length, fail
call get_eaddr ; address to caller's area
mov ax,ds
mov es,ax
mov di,offset address ; where to store Ethernet address
call get_eaddr ; get board's Ethernet address
jmp good_ret
get_address_err:
mov dh,NO_SPACE ; hmmm, I suppose it's close enough
jmp err_ret
; Return board's current Ethernet address in es:di (ETHERADDR_LEN bytes)
; via NDIS information.
get_eaddr proc near
push ds
push si
push cx
push es ; preserve destination
push di
les si,mac_cctp ; get address of mac cct
lds si,es:sscp[si] ; get address of mac ssc
add si,cur_add ; mov to offset in structure
pop di
pop es
mov cx,ETHERADDR_LEN ; get length
cld
rep movsb ; copy address
pop cx
pop si
pop ds
ret
get_eaddr endp
;
; Perform reset_interface() - this is ignored.
;
reset_interface:
call chk_hdl ; check handle
jmp good_ret ; if the handle was good, call is good
;
; The following implement the High Performance functions
;
; get_parameters() - Return pointer to parameters structure in ES:DI
;
get_parameters:
mov ax,cs
mov _ES[bp],ax ; return struct adr in caller's ES:DI
mov _DI[bp],offset pd_param
jmp good_ret ; & pass it to caller
;
; as_send_pkt() - Not implemented.
;
;as_send_pkt:
; mov dh,BAD_COMMAND
; jmp err_ret
;
; The following implement the Extended functions
;
; set_rcv_mode translates the PDS mode to an NDIS Packet Filter.
;
set_rcv_mode:
call chk_hdl ; get handle, return here if ok
mov ax,_AX[bp]
mov cx,_CX[bp]
jcxz set_rcv_mode_err ; z = illegal receive mode, quit
cmp cx,6 ; is mode legal?
ja set_rcv_mode_err ; a = no, quit
mov bx,cx ; Put it in an index register
mov bl,ndis_mode[bx] ; and translate it for NDIS
xor bh,bh
cmp bl,4 ; NDIS Promiscuous mode?
jb set_rec_mode2 ; b = no
push es
push di
les di,mac_cctp ; check if Promiscuous mode supported
les di,es:[di].sscp
test es:[di].svc_1,8 ; first 15 service flags, Promis bit
jnz set_rec_mode1 ; nz = mode is supported
dec bl ; use regular NDIS mode 3 instead
set_rec_mode1:
pop di
pop es
set_rec_mode2:
call set_ndis_mode ; Try to set it
cmp ax,SUCCESS ; did it succeed?
je set_rcv_mode_ok ; e = yes, return success
set_rcv_mode_err:
mov dh,BAD_MODE ; no, return error
jmp err_ret
set_rcv_mode_ok:
mov bx,_BX[bp] ; get handle again
mov cs:[bx].pd_conn_rmode,cx ; set receive mode in handle's struct
mov cs:pd_rcv_mode,cx ; save the mode we just set
call chk_rmode ; check on Promiscous mode
jmp good_ret ; and return ok
; Examine all PD handles and set global variable pd_recvall to 0 if no handle
; is doing Promiscuous mode receives, else non-zero.
chk_rmode proc near
push bx
push cx
push ds
mov cx,cs
mov ds,cx
mov bx,offset handles ; BX = offset of handle table
mov cx,PD_MAX_CONNS ; CX = entries in table
mov pd_recvall,0 ; assume no Promiscous mode active
chk_rmode1:
cmp [bx].pd_conn_used,0 ; is handle in use?
je chk_rmode2 ; e = no, do next handle
cmp [bx].pd_conn_rmode,6 ; Promiscuous mode active here?
jne chk_rmode2 ; ne = no
mov pd_recvall,1 ; say Promiscous mode is active
jmp short chk_rmode3
chk_rmode2:
loop chk_rmode1
chk_rmode3:
pop ds
pop cx
pop bx
ret
chk_rmode endp
;
; Return the current Packet Driver receive mode.
;
get_rcv_mode:
call chk_hdl ; get handle, return here if ok
mov ax,[bx].pd_conn_rmode ; get mode for this handle
mov _AX[bp],ax
jmp good_ret ; return it
get_statistics:
les si,mac_cctp ; ES:SI == address of NDIS cct
les si,es:sssp[si] ; ES:SI == address of NDIS sss
mov ax,es
or ax,ax ; Is the segment non-zero?
jnz getsta1 ; nz = yes, accept it
or si,si ; how about offset?
jnz getsta1 ; nz = ok
mov DH,BAD_COMMAND ; If they don't implement it,
jmp err_ret ; neither do we
getsta1:mov ax,cs
mov ds,ax
mov di,offset pd_stat ; Get start of PD stats table
cli ; Don't allow updates just now
mov ax,WORD PTR es:r_tot[si] ; Copy total received frames
mov dx,WORD PTR es:r_tot+2[si]
call valchk
mov ax, WORD PTR es:x_tot[si] ; Copy total xmitted frames
mov dx, WORD PTR es:x_tot+2[si]
call valchk
mov ax, WORD PTR es:rb_tot[si] ; Copy total received bytes
mov dx, WORD PTR es:rb_tot+2[si]
call valchk
mov ax, WORD PTR es:xb_tot[si] ; Copy total transmitted bytes
mov dx, WORD PTR es:xb_tot+2[si]
call valchk
mov ax, WORD PTR es:r_err[si] ; Copy total receive errors
mov dx, WORD PTR es:r_err+2[si]
call valchk
mov ax, WORD PTR es:x_hwer[si] ; Copy total transmit errors
mov dx, WORD PTR es:x_hwer+2[si]
call valchk
mov ax, WORD PTR es:r_drop[si] ; Copy total receives dropped
mov dx, WORD PTR es:r_drop+2[si]
call valchk
sti ; All done with shared data
mov _SI[bp],OFFSET pd_stat ; set caller's DS:SI to the
mov ax,cs ; address of Packet Driver stats
mov _DS[bp],ax
jmp good_ret
; Convert double word dx:ax from NDIS unknown value of (long) -1 to (long) 0,
; store results in ds:[di, di+2], move di forward two words.
valchk proc near
cmp ax,-1 ; starting at -1 (NDIS, for unknown)?
jne valchkx ; ne = no
cmp dx,-1 ; this part too
jne valchkx ; ne = no
xor ax,ax ; zero counters for zero based counts
xor dx,dx
valchkx:mov [di],ax ; store results locally
mov [di+2],dx
add di,4 ; step to next storage double word
ret
valchk endp
;
; Perform set_address() - change physical address of the interface.
;
; The problem with this is that some NDIS drivers may just accept the
; SetStationAddress call, but others may require a CloseAdapter/OpenAdapter
; to bracket it. This latter doesn't seem worth the effort at the moment.
;
set_address:
IFDEF DO_SET_ADDRESS
mov bx,_BX[bp] ; Get handle (not checked)
mov cx,_CX[bp]
cmp cx,ETHERADDR_LEN ; Make sure it's an ethernet address
jne set_address_err ; Jump if bad length
cmp conn_in_use,1 ; How many handles are open?
jbe set_allowed ; be = 1 or none, ok
set_err:
mov dh,CANT_SET ; Too many - don't allow it
jmp err_ret
set_allowed:
mov ax, cs:drv_cct.mod_id ; Make set station address call
push ax ; Module ID of protocol
inc ax
push ax ; Push request ID (0 to not conf)
xor bx,bx
push bx ; Must be 0
push es ; Push pointer to address to set
push di
push SET_STA_ADDR ; SetStationAddress function code
les bx,mac_cctp
mov ax,es:[bx].mod_ds
push ax
mov cs:req_con_flg,REQUEST_QUEUED
call cs:Request ; Make call to NDIS
mov cs:req_con_flg,ax
sti ; Wait for request to complete
setall1:
cmp ax,SUCCESS ; success?
je setall2 ; e = yes
cmp ax,REQUEST_QUEUED ; Is it queued?
jne set_err ; ne = no, quit with CANT_SET
mov ax,cs:req_con_flg ; get current status
jmp short setall1 ; keep polling
setall2:jmp good_ret
set_address_err:
mov dh, BAD_ADDRESS ; We didn't like the address
jmp err_ret
ELSE
mov dh, CANT_SET ; Built this way, we can't set address
jmp err_ret
ENDIF
pd_isr ENDP
;;;;;; end of Packet Driver direct support procedures
;
; The following are upcalls from DIS:
; RequestConfirm enters with stack of (after our push bp)
; dw [BP+16] ProtID
; dw [BP+14] MACID
; dw [BP+12] ReqHandle
; dw [BP+10] Status
; dw [BP+8] Request
; dw [BP+6] ProtDS (our DS)
req_con PROC FAR ; Request Confirm
push bp
mov bp,sp
mov ax,[bp+10] ; get NDIS status response
mov cs:req_con_flg,ax ; store in local area
mov ax,SUCCESS ; return our feelings on the matter
pop bp
ret 12
req_con ENDP
; TransmitConfirm enters with stack of (after our push bp)
; dw [BP+14] ProtID
; dw [BP+12] MACID
; dw [BP+10] ReqHandle
; dw [BP+8] Status
; dw [BP+6] ProtDS (our DS)
xmt_con PROC FAR ; Transmit Confirm
push bp
mov bp,sp
mov ax,8[bp]
mov cs:xmt_cmp,ax ; moves the return code into static
mov ax,SUCCESS
pop bp
ret 10
xmt_con ENDP
sta_ind PROC FAR ; Status handled, not used
mov ax,SUCCESS
ret 12
sta_ind ENDP
dis_pat PROC FAR ; System entry point for pkt driver
push bp ; Used only by initiate bind request
mov bp,sp
mov ax,8[bp] ; Check opcode
cmp ax,1 ; Is it initiate_bind?
je dispat1 ; e = yes
mov ax,GENERAL_FAILURE ; NO: fail
pop bp
ret 14
dispat1:push ds ; save stuff
push es
push bx
push cx
push si
push di
mov ax,cs ; set up DS == CS
mov ds,ax
mov bx,offset mac_cctp ; Save addr of MAC's cct
mov ax,12[bp]
mov [bx],ax
mov ax,14[bp]
mov 2[bx], ax
mov ax,offset drv_cct ; push pkt drv cct (our cct)
push ds
push ax
mov ax,offset mac_cctp ; push addr for MAC's cct
push ds
push ax
xor ax,ax ; pad parameter
push ax
mov ax,2 ; Load Bind command code
push ax
les bx,mac_cctp ; load address of MAC's cct
mov ax,es:[bx].mod_ds
push ax ; push MAC's ds
call dword ptr es:[bx].system ; call MAC's system entry point
mov rtn_cod,ax ; remember return status
or ax,ax
jz dispat2 ; z = Bind succeeded
MSG bad_bind ; tell the user the bad news
jmp rtn_dis ; Bind failed, fatal error
dispat2:
call sav_mac ; Save MAC entry point addresses
les bx,mac_cctp ; Check if OpenAdapter needed
les bx,es:[bx].sscp
lea di,[bx].mtype ; MAC type, asciiz
mov si,offset t8023 ; try 802.3
mov cx,t8023len
cld
repe cmpsb
je is8023 ; e = matched
lea di,[bx].mtype
mov si,offset t8025 ; try 802.5 (Token Ring)
mov cx,t8025len
repe cmpsb
je is8025 ; e = matched
jmp short gottype
is8023: mov if_class,11 ; 802.3 with 802.2 (SNAP) headers
mov off,14 ; 6 MAC + 6 MAC + 2 LEN
jmp short gottype
is8025: mov if_class,3 ; Token Ring 802.5
mov off,14
mov aoff,2
mov ax,es:[bx].maxfram
mov mtu,ax
; jmp short gottype
gottype:mov ax,es:[bx].svc_1
test ax,0800h ; OpenAdapter supported?
jnz dispat3 ; nz = yes, go do it
jmp open_ok1 ; skip to setting packet filter
dispat3: ; Make OpenAdapter call to NDIS
mov ax,cs
push ax ; module ID of protocol
push ax ; unique handle (0 to not conf)
ifdef ALLFRAMES
mov ax, 6
push ax
endif
xor ax,ax
ifndef ALLFRAMES
push ax ; dw pad
endif
push ax ; dd pad
push ax
mov ax,OPEN_ADAPTER ; OpenAdapter command code
push ax
les bx,mac_cctp
mov ax,es:[bx].mod_ds
push ax
mov cs:req_con_flg,REQUEST_QUEUED
call cs:Request ; Make call to NDIS via indirect ptr
mov cs:req_con_flg,ax ; Save immediate return code
dispat4:sti ; Needed because of bugs in some MACs
cmp ax,SUCCESS
jz open_ok1
cmp ax,NOT_SUPPORTED
jz open_ok1
cmp ax,REQUEST_QUEUED ; Was it queued?
jne dispat5 ; NO: bomb
mov ax,cs:req_con_flg
jmp short dispat4 ; keep polling
dispat5:MSG bad_open_adpt ; Fatal error: open adapter failed
jmp rtn_dis
open_ok1:
mov ax,cs ; Temp fix for Apricot (may not
mov ds,ax ; be needed anymore)
mov ax,mac_ds
push ax
call IndicationOff
mov ax,mac_ds
push ax
call IndicationOn
sti ; Who disabled? MAC bug probably
mov bx,3 ; Set default filter: Directed,
call set_ndis_mode ; Multicast & Broadcast (3)
cmp ax,SUCCESS ; Did it work?
je set_vec ; e = yes, go on to vector
MSG bad_set_pkt ; show an error and fail
jmp rtn_dis
; Give warning if the Packet Driver vector is already in use but use anyway
set_vec:
xor ax,ax ; Set ES to 0 to look in int tab
mov es,ax
mov bx,cs:pd_vector ; Get vector and multiply by 4
shl bx,1
shl bx,1
mov ax,es:[bx]
or ax,ax ; Is segment zero?
jnz vin_use2 ; nz = yes, print warning
mov ax,es:2[bx]
or ax,ax ; Is offset zero?
jz dispat6 ; z = no, don't print warning
vin_use2:
MSG vec_in_use ; Print a warning
dispat6:
mov ax,offset pd_isr ; move packet driver isr addr into
mov es:[bx],ax ; interrupt vector table
mov ax,cs
mov es:2[bx],ax
xor ax,ax
rtn_dis:
pop di ; all done
pop si
pop cx
pop bx
pop es
pop ds
pop bp
ret 14
dis_pat ENDP
; Make the NDIS SetPktFilter call (both at bind and from set_rcv_mode)
;
; Arguments:
; BX NDIS Packet filter to set (see DIS p 45 for bits)
; * 0 - directed and multicast
; * 1 - broadcast
; 2 - promiscuous
; 3 - any source routing packet
;
set_ndis_mode PROC NEAR
push es ; Save ES & BX registers
push bx
mov ax,cs:drv_cct.mod_id ; make set packet filter call
push ax ; module ID of protocol
inc ax
push ax ; unique handle (0 to not conf)
push bx ; Push packet filter value
xor ax,ax
push ax ; dd pad
push ax
mov ax,SET_PKT_FLT ; SetPacketFilter command
push ax
les bx,mac_cctp
mov ax,es:[bx].mod_ds
push ax
mov cs:req_con_flg,REQUEST_QUEUED
call cs:Request ; Make call to NDIS
mov cs:open_adap,ax
sti ; Wait for request to complete
setndmode1:
cmp ax,SUCCESS ; done?
jz setndmode2 ; z = yes, success
cmp ax,REQUEST_QUEUED ; Is it queued?
jne setndmode2 ; ne = no, fail
mov ax,cs:req_con_flg ; get current status
jmp setndmode1 ; keep polling
setndmode2:
pop bx
pop es
ret ; NDIS return code is in AX
set_ndis_mode ENDP
;
; Put MAC entry points into static locations - called at bind time.
;
sav_mac PROC NEAR
push ax
les si,mac_cctp
mov ax,es:[si].mod_ds ; save MAC ds
mov mac_ds, ax
les si,es:[si].udtp
mov bx,offset Request ; save request entry point
mov ax, es:4[si]
mov [bx],ax
mov ax,es:6[si]
mov 2[bx], ax
mov bx,offset TransmitChain ; save xmt block entry point
mov ax,es:8[si]
mov [bx],ax
mov ax,es:10[si]
mov 2[bx],ax
mov bx,offset TransferData ; save xfer data entry point
mov ax,es:12[si]
mov [bx],ax
mov ax,es:14[si]
mov 2[bx],ax
mov bx,offset ReceiveRelease ; save recv rel entry point
mov ax,es:16[si]
mov [bx],ax
mov ax,es:18[si]
mov 2[bx],ax
mov bx,offset IndicationOn ; save ind on entry point
mov ax,es:20[si]
mov [bx],ax
mov ax,es:22[si]
mov 2[bx],ax
mov bx,offset IndicationOff ; save ind off entry point
mov ax,es:24[si]
mov [bx],ax
mov ax,es:26[si]
mov 2[bx],ax
pop ax
ret
sav_mac ENDP
; Message strings needed at bind time.
bad_open_adpt db "Adapter did not open", EOL
bad_set_pkt db "Set packet filter failed", EOL
vec_in_use db "Vector already in use", EOL
bad_bind db 7,"BIND failed",EOL
t8023 db '802.3',0
t8023len equ $-t8023
t8025 db '802.5',0
t8025len equ $-t8025
end_res: ;;;; Currently not keeping init code in memory
;
; DOS device driver interrupt entry point.
;
; This is used to initialize module and read parameters from PROTOCOLS.INI
; only, and frees itself after startup. The NDIS bind takes place later,
; via dis_pat and its friends above.
;
intr PROC FAR
push es ; save all registers
push ds
push si
push di
push dx
push cx
push bx
push ax
mov ax,cs ; check to see if already initialized
mov ds,ax
mov al,init_flg ; our init flag
or al,al ; not inited yet (0)?
jz intr1 ; z = yes, init now
mov bx,req_off ; already initialized - return
mov ds,req_seg ; with error
mov [bx].status, 810Ch
jmp rtn
intr1: cli ; not initialized - switch to new
mov si,SS ; stack and init
mov dx,SP
mov ax,CS
mov SS,ax
mov SP,OFFSET new_stk ; Need a big stack for this call
STI ; Critical region
PUSH SI ; Save old SS
PUSH DX ; and SP
MSG msg_copyright ; Display copyright notice
call init ; Init this driver
mov ax,cs ; Set DS == CS
mov ds,ax
mov bx,req_off ; Get request header ptr
mov es,req_seg
mov word ptr es:[bx].status,0100h ; Set return status ok
mov init_flg,1 ; Note that we've initialized
mov ax,offset end_res ; Set end of resident code
mov word ptr es:[bx].end_off,ax
mov ax,cs
mov es:[bx].end_seg,ax
POP DI ; Old SP
POP SI ; and old SS
CLI ; Critical region
mov SS, SI ; Change back to old stack
mov SP, DI
STI ; End critical region
rtn: pop ax ; All done
pop bx
pop cx
pop dx
pop di
pop si
pop ds
pop es
ret
intr ENDP
db 512 dup (0)
new_stk label word ; A stack for init to use
db 4 dup (0)
fil_han dw 0 ; File handle for init
;
; Initialize the converter module - read parameters from PROTOCOLS.INI.
;
init PROC NEAR
mov ax,cs ; open the Protocol Manager driver
mov ds,ax
mov ah,fopen ; open file
mov al,0C2h
mov dx,offset pm__nam ; device name
int dos
jnc init1 ; nc = success
MSG pro_no_open ; error
jmp init_err
init1: mov fil_han,ax ; file handle
mov bx, ax
mov ax, cs
mov ds, ax
mov drv_req.req_opc,1 ; make GetProtocolManagerInfo call
mov drv_req.req_sta,-1 ; zero out return status
mov drv_req.req_of1,-1 ; NULL out pointers
mov drv_req.req_sg1,-1
mov drv_req.req_of2,-1 ; NULL out pointer 2
mov drv_req.req_sg2,-1
mov drv_req.req_prm,-1 ; zero out parameter word
mov ah,ioctl ; IOCTL req
mov al,02h ; device input
mov dx,offset drv_req ; pointer to buffer
mov cx,14 ; size of buffer
int dos ; call DOS
jnc init2 ; nc = success
MSG pro_bad_gpm ; Error: print msg & bomb
jmp init_err
init2: mov ax, cs ; restore ds
mov ds, ax
mov ax,offset pro_nam ; Get name of module to bind to,
push ax ; returned by get_pro in ES:DI
mov ax,pro_nam_len
push ax
mov ax,offset pro_bnd_to
push ax
mov ax,pro_bnd_to_len
push ax
xor ax,ax
push ax
call get_pro ; Try to find the token we want
or di,di ; Was it there?
jnz init4 ; nz = yes, parse it
mov drv_bnd.bnd_cnt,0 ; else say nothing bound
jmp short init45
init4: push ds ; Save name in bindings structure
push ds ; currently allowed to bind to only
push es ; one MAC
pop ds
pop es
mov si,di
mov di,offset drv_bnd.bnd_nam
mov cx,-2[si]
cld
rep movsb
pop ds
init45: mov ax,offset pro_nam ; Get Packet Driver vector to use
push ax
mov ax,pro_nam_len
push ax
mov ax,offset pro_prm_vec ; "INTVEC" keyword
push ax
mov ax,pro_prm_vec_len
push ax
xor ax,ax
push ax
call get_pro ; Go look for the token
or di,di ; Was the token found?
jnz init5 ; nz = yes
MSG vec_not_spc ; abort if not found
jmp init_err
init5: mov dx,es:[di] ; check that vector is in range
cmp dx,80h ; 0x80 is high limit
jge bad_vec2
cmp dx,60h ; 0x60 is low limit
jl bad_vec2
mov pd_vector,dx ; Save value for bind time
jmp short init6 ; Go on to EOI interrupt
bad_vec2:
MSG msg_bad_vec ; Abort if out of range
jmp init_err
init6: mov ax,offset pro_nam ; Get EOI interrupt (if any)
push ax
mov ax,pro_nam_len
push ax
mov ax,offset pro_daisy_vec ; "CHAINVEC" key word
push ax
mov ax,pro_daisy_len
push ax
xor ax,ax
push ax
call get_pro ; Try to find the token
or di,di
jz init7 ; z = no interrupt
mov dx,es:[di] ; Check that interrupt is ok
cmp dx,80h ; High limit is 0x80
jae bad_vec3 ; ae = above high limit
cmp dx,60h ; Low limit is 0x60
jb bad_vec3 ; b = below lower limit
mov byte ptr ind_int+1,dl ; Modify the code
mov param_int, dx ; Save interrupt number
jmp short init7 ; Go do the RegisterModule
bad_vec3:
MSG msg_bad_vec
jmp init_err ; Abort installation
init7: mov ax,offset pro_nam ; Get old Novell 802.3 keyword
push ax
mov ax,pro_nam_len
push ax
mov ax,offset pro_novell ; "NOVELL" key word
push ax
mov ax,pro_nov_len
push ax
xor ax,ax
push ax
mov novell,0 ; assume no token
call get_pro ; Try to find the token
or di,di
jz init8 ; z = no token
mov dx,es:[di] ; get the token's value
and dl,not 20h ; to upper case
cmp dl,'Y' ; "yes"?
jne init8 ; ne = no conversion
mov novell,1 ; set flag
MSG novmsg ; tell the user about conversion
init8: call pkt_ptr ; Initialize the LDT and CCT pointers
mov ax,cs
mov ds,ax
mov drv_req.req_opc,2 ; RegisterModule call
mov drv_req.req_sta,0 ; zero out return status
mov drv_req.req_of1,offset drv_cct ; cct pointer
mov drv_req.req_sg1,ax
mov drv_req.req_of2,offset drv_bnd
mov drv_req.req_sg2,ax
mov drv_req.req_prm,0 ; zero out parameter word
mov ah,ioctl ; IOCTL call
mov al,2
mov dx,offset drv_req
mov cx,14
mov bx,fil_han
int dos
mov ax,drv_req.req_sta ; check return status
cmp ax,SUCCESS
je init9 ; e = success
mov cs:rtn_cod,ax ; abort if reg mod failed
MSG reg_mod_nok
jmp init_err
init9: mov bx,fil_han ; Close protman device
mov ah,fclose
int dos
jc init10 ; c = failure
xor ax,ax ; Indicate success
ret ; & do normal return
init10: MSG msg_err_clo ; close failed, quite unlikely
jmp init_err
init_err:mov ax,1 ; error return
ret
init ENDP
; get_pro returns a pointer to the keyword entry from GPMI call
; 12[bp] is a pointer to module name
; 10[bp] is length of module name
; 8[bp] is a pointer to keyword name
; 6[bp] is length of keyword name
; 4[bp] is number of parameter wanted from specified keyword
;
; returns
; es:bx is pointer to param
; ax zero for ok and !0 for not found
;
get_pro PROC NEAR
push bp
mov bp,sp
push ds
push bx
push si
lds bx,dword ptr drv_req.req_of1 ; ConMemIma pointer
mov ax,cs ; find module name
mov es,ax
getpro1:mov ax,ds ; quit if pointer NULL (eol)
or ax,ax
jz err_get_pro ; z = error
mov di,12[bp] ; module name
mov si,bx ; set up to point name
add si,8
mov cx,10[bp] ; module name length
cld
repe cmpsb ; right module name?
je pro_fnd ; e = module name found
lds bx,dword ptr [bx] ; not found-load next in chain
jmp short getpro1
pro_fnd:
add bx,24 ; offset of parameter pointers
getpro2:
mov ax,ds
or ax,ax
jz err_get_pro
mov di,8[bp] ; parameter name
mov cx,6[bp] ; parameter name length
mov si,bx
add si,8
cld
repe cmpsb
je key_fnd ; e = parameter found
lds bx,dword ptr [bx] ; not found-load next in chain
jmp short getpro2
key_fnd:
add bx,24 ; offset of values
mov cx,4[bp] ; check if enough values are
cmp cx,[bx] ; here
jge err_get_pro
add bx,2 ; position to the value
jcxz prm_fnd ; may be either char string
getpro3: ; or number depending on type
add bx,2
add bx,[bx]
add bx,2
loop getpro3
prm_fnd:
mov si,bx ; set es:di to point to value
add si,4
mov cx,2[bx]
mov ax,ds
mov es,ax
mov di,si
jmp short getpro4
err_get_pro:
; MSG pro_not_fnd ; error return
xor ax,ax
mov es,ax
mov di,ax
getpro4:
pop si ; common return
pop bx
pop ds
pop bp
ret 10
get_pro ENDP
pkt_ptr PROC NEAR ; Set up pointers in Packet
mov ax,cs ; Driver ldt and cct
mov ds,ax ; Note:most of the could
mov bx,offset drv_ldt ; (should) be done statically
mov word ptr [bx],offset drv_cct ; driver's cct back pointer
mov 2[bx], ax
add bx,8 ; skip int flgs
mov [bx],offset req_con ; RequestConfirm address
mov 2[bx],ax
mov 4[bx],offset xmt_con ; TransmitConfirm address
mov 6[bx],ax
mov 8[bx],offset rcv_lah ; ReceiveLookahead indication
mov 10[bx],ax
mov 12[bx],offset ind_com ; IndicationComplete address
mov 14[bx],ax
mov 16[bx],offset rcv_chn ; ReceiveChain indication add
mov 18[bx],ax
mov 20[bx],offset sta_ind ; status indication address
mov 22[bx],ax
mov bx,offset drv_cct.ldtp ; set up point to drv ldt
mov word ptr [bx],offset drv_ldt
mov 2[bx],ax
;
;set up pointers in pkt driver cct
; only doing lower dispatch table, all other left NULL
; hopefully this will work
;
mov drv_cct.mod_id,-1
mov drv_cct.mod_ds,ax
mov bx,offset drv_cct.system
mov [bx],offset dis_pat ; drv system func entry point
mov 2[bx],ax ; drv ds
mov word ptr 16[bx],offset drv_ldt ; ptr to ldt
mov 18[bx],ax
ret
pkt_ptr ENDP
; Text messages that can be flushed after startup but before bind.
msg_no_vect db "Vector not specified", EOL
msg_bad_vec db "Invalid vector (must be 60h-7Fh)",EOL
msg_err_clo db "Error closing MAC driver", EOL
msg_copyright db "MAC/DIS to Packet Driver converter loaded."
db " Version 1.09",CR,LF
db "Copyright 1991 FTP Software, Inc. All rights "
db "reserved.", cr,lf
db " v1.07 by Joe R. Doupnik, jrd@cc.usu.edu, "
db "Utah State Univ, 18 May 1991", cr,lf
db " v1.08 by Dan Lanciani, ddl@harvard.harvard.edu",cr,lf
db " v1.09 by Joe R. Doupnik, jrd@cc.usu.edu, "
db "Utah State Univ, 3 Nov 1991",EOL
pm__nam db "protman$", 0
pro_no_open db "Protocol Manager not present", EOL
pro_bad_gpm db "GetProtocolManagerInfo call failed", EOL
pro_nam db "PKTDRV",0
pro_nam_len equ $ - pro_nam
pro_prm_vec db "INTVEC",0
pro_prm_vec_len equ $ - pro_prm_vec
pro_daisy_vec db "CHAINVEC",0
pro_daisy_len equ $ - pro_daisy_vec
pro_prm_nok db "SINTVECXX",0
pro_prm_nok_len equ $ - pro_prm_nok
pro_bnd_to db "BINDINGS",0
pro_bnd_to_len equ $ - pro_bnd_to
pro_novell db "NOVELL",0
pro_nov_len equ $ - pro_novell
novmsg db "Using OLD NOVELL 802.3 packets on the wire",EOL
vec_not_spc db "Interrupt vector for Packet Driver not specifed"
db " in PROTOCOL.INI", EOL
reg_mod_nok db "Register module call failed", EOL
CSEG ends
end